<template>
  <div class="vk-timer">
    <!-- 天 -->
    <div class="vk-timer__item" :style="fontStyles" v-if="isDays">
      {{ d }}
    </div>
    <div class="vk-timer__colon" :style="colonStyles" v-if="isDays">
      {{ isColon ? ":" : "天" }}
    </div>
    <!-- 时 -->
    <div class="vk-timer__item" :style="fontStyles" v-if="isHours">
      {{ addZero(h) }}
    </div>
    <div class="vk-timer__colon" :style="colonStyles" v-if="isHours">
      {{ isColon ? ":" : "时" }}
    </div>
    <!-- 分 -->
    <div class="vk-timer__item" :style="fontStyles" v-if="isMinutes">
      {{ addZero(m) }}
    </div>
    <div class="vk-timer__colon" :style="colonStyles" v-if="isMinutes">
      {{ isColon ? ":" : "分" }}
    </div>
    <!-- 秒 -->
    <div class="vk-timer__item" :style="fontStyles" v-if="isSeconds">
      {{ addZero(s) }}
    </div>
    <div class="vk-timer__colon" :style="colonStyles" v-if="isSeconds && isMs">
      {{ isColon ? "." : "秒" }}
    </div>
    <!-- 毫秒 -->
    <div class="vk-timer__ms" :style="fontStyles" v-if="isMs">
      <div :class="{ 'timer-ms__list': isAni }">
        <div class="timer-ms__item" v-for="(item, i) in ms" :key="i">
          {{ item }}
        </div>
      </div>
    </div>
    <div class="vk-timer__colon" :style="colonStyles" v-if="isMs">
      {{ isColon ? "" : "毫秒" }}
    </div>
  </div>
</template>

<script>
export default {
  name: "VkTimer",
  //   emits: ["end"],
  props: {
    //初始时间 (单位：秒)
    value: {
      type: [Number, String],
      default: 0,
    },
    //最大时间，大于等于最大时间则计时结束，为0则需要手动结束 (单位：秒)
    maxTime: {
      type: Number,
      default: 0,
    },
    //数字框高度
    height: {
      type: Number,
      default: 36,
    },
    //数字框border颜色
    borderColor: {
      type: String,
      default: "transparent", // 透明
    },
    //数字框背景颜色
    backgroundColor: {
      type: String,
      default: "transparent",
    },
    //数字框字体大小
    size: {
      type: Number,
      default: 32,
    },
    //数字框字体颜色
    color: {
      type: String,
      default: "#333",
    },
    //冒号或文字大小
    colonSize: {
      type: Number,
      default: 32,
    },
    //冒号或文字颜色
    colonColor: {
      type: String,
      default: "#333",
    },
    //是否显示天
    isDays: {
      type: Boolean,
      default: false,
    },
    //是否显示小时
    isHours: {
      type: Boolean,
      default: true,
    },
    //是否显示分钟
    isMinutes: {
      type: Boolean,
      default: true,
    },
    //是否显示秒数
    isSeconds: {
      type: Boolean,
      default: true,
    },
    // 是否展示毫秒
    isMs: {
      type: Boolean,
      default: false,
    },
    //时分秒是否展示为冒号,false为文字
    isColon: {
      type: Boolean,
      default: true,
    },
    // 是否自动开始计时
    start: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      d: "0", // 天
      h: "0", // 时
      s: "0", // 分
      m: "0", // 秒
      ms: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], // 毫秒只展示0-9
      timer: null, // 定时器
      seconds: 0, // 秒数
      isAni: false, // 是否开启动画
    };
  },

  created() {
    this.initializeTime(this.value);
    this.start && this.startTimer();
  },

  computed: {
    // 字体样式
    fontStyles() {
      return {
        height: this.height + "px",
        lineHeight: this.height + "px",
        borderColor: this.borderColor,
        backgroundColor: this.backgroundColor,
        color: this.color,
        fontSize: this.size + "px",
      };
    },
    // 冒号样式
    colonStyles() {
      return {
        color: this.colonColor,
        lineHeight: this.height + "px",
        fontSize: this.colonSize + "px",
      };
    },
  },

  beforeDestroy() {
    this.timer && clearInterval(this.timer);
  },

  // 00:00:00
  methods: {
    // 初始化时间
    initializeTime(value) {
      const totalSeconds = parseInt(value, 10);
      this.seconds = totalSeconds;
      if (this.seconds > 0) {
        this.d = this.isDays ? Math.floor(totalSeconds / (24 * 60 * 60)) : 0;
        this.h = this.isHours
          ? Math.floor(totalSeconds / (60 * 60)) - this.d * 24
          : 0;
        this.m = this.isMinutes
          ? Math.floor(totalSeconds / 60) - this.h * 60 - this.d * 24 * 60
          : 0;
        this.s = this.isSeconds
          ? Math.floor(totalSeconds) -
            this.d * 24 * 60 * 60 -
            this.h * 60 * 60 -
            this.m * 60
          : 0;
      }
    },

    // 开始计时
    startTimer() {
      this.clearTimer();
      this.isAni = true;
      this.timer = setInterval(() => {
        if (this.seconds >= this.maxTime && this.maxTime != 0) {
          this.stopTimer();
          return;
        }
        this.s++;
        this.seconds++;
        if (this.s > 59) {
          this.s = 0;
          this.m++;
          if (this.m > 59) {
            this.m = 0;
            this.h++;
            if (this.isDays && this.h > 24) {
              this.h = 0;
              this.d++;
            }
          }
        }
      }, 1000);
    },

    // 补零
    addZero(num) {
      return num < 10 ? "0" + num : num.toString();
    },

    // 停止计时
    stopTimer() {
      this.clearTimer();
      this.$emit("end", {
        days: this.d,
        hour: this.h,
        minute: this.m,
        second: this.s,
        totalSeconds: this.seconds,
      });
    },

    // 重置计时
    resetTimer() {
      this.d = "0";
      this.h = "0";
      this.s = "0";
      this.m = "0";
      this.seconds = 0;
      this.clearTimer();
      this.startTimer();
    },

    // 清除定时器
    clearTimer() {
      this.isAni = false;
      this.timer && clearInterval(this.timer);
    },
  },
};
</script>

<style scoped>
.vk-timer {
  display: flex;
  align-items: center;
}
.vk-timer__item,
.vk-timer__colon {
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 5px;
}
.vk-timer__colon {
  margin: 0 5px;
}

.vk-timer__ms {
  overflow: hidden;
  border-radius: 5px;
}

/*ms使用css3代替js频繁更新操作，性能优化*/
.timer-ms__list {
  animation: loop 1s steps(10) infinite; /* 1s内循环10次 ,infinite 表示无限循环 */
}

@keyframes loop {
  from {
    transform: translateY(0);
  }

  to {
    transform: translateY(-100%);
  }
}
</style>
